#pragma once

#include <iostream>
using namespace std;
#include <functional>
#include <string>
#include <cstring>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>

#define BUFSIZE 1024

void serverIO(int sock, struct sockaddr_in *clientinfor)
{
    // 从sock中读取数据,再将处理后的数据发送回客户端
    char recvbuffer[BUFSIZ];
    char sendbuffer[BUFSIZ];
    string clientip = inet_ntoa(clientinfor->sin_addr); // 将四字节IP地址转字符串形式

    while (true)
    {
        // 读取数据
        int n = read(sock, recvbuffer, sizeof(recvbuffer) - 1);
        if (n <= 0)//读取失败/写端已退出
        {
            char buffer[BUFSIZ];
            snprintf(buffer, sizeof(buffer), "client %s[%d] quit", clientip.c_str(), ntohs(clientinfor->sin_port));

            cout << buffer << endl;
            break;
        }

        // 读取数据成功
        recvbuffer[n] = 0; // 在读取到的数据后面设置一个\0

        // 格式化要发送回客户端的数据
        snprintf(sendbuffer, sizeof(sendbuffer), "server received a message from %s[%d], message:%s", clientip.c_str(), ntohs(clientinfor->sin_port), recvbuffer);

        cout << sendbuffer << endl;//打印消息

        // 将处理后的数据发送回客户端
        write(sock, sendbuffer, strlen(sendbuffer));
    }

    //任务执行完成，关闭文件
    close(sock);
}

class task
{
    typedef function<void(int, struct sockaddr_in *)> func;

public:
    // 默认构造
    task()
    {
    }

    // 传参构造
    task(int sock, const struct sockaddr_in &clientinfor, func callback)
        : _sock(sock), _clientinfor(clientinfor), _callback(callback)
    {
    }

    void operator()()
    {
        _callback(_sock, &_clientinfor);
    }

private:
    int _sock;
    struct sockaddr_in _clientinfor;
    func _callback;
};